<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>中文代码玩3D</title>
    <style>
        body {
            margin: 0;
        }

        #code {
            display: none;
        }
    </style>
    <script async src="/es-module-shims/dist/es-module-shims.js"></script>
    <script type="importmap">
        {
        "imports": {
          "three": "/three/build/three.module.js",
          "three/addons/": "/three/examples/jsm/",
          "three/examples/jsm/": "/three/examples/jsm/"
        }
      }
    </script>
</head>

<body>
    <script id="我的场景" type="domElement">
        <场景>
          <透视摄像机 视野角度="50" 长宽比="自适应" 最小可视范围="0.1" 最大可视范围="2000" />
          <控制器 类型="轨道">
              <参数 类型="位置" x="0" y="4" z="20" />
              <参数 类型="聚焦" x="0" y="4" z="0" />
          </控制器>
          <!-- <全景视频  路径="/demo.mp4"  循环="true"  静音="false"  自动播放="true" /> -->
          <全景图片  路径="/three-js-es@1.0.0/movie.jpg" />
          <!-- <VR镜头 /> -->
          <文字精灵 文本="🤞\n你好，世界！" 字体="Arial" 字号="30" 字体颜色="#ffffff" 字体边框颜色="#000000" 
            字体边框线宽="0" 对齐方式="center" 背景边框颜色="#ffff0099" 背景颜色="#00ff0000" 字间距="2"  行高="40">
            <参数 类型="位置" x="0" y="7" z="0" />
          </文字精灵>
          <物体>
              <参数 类型="位置" x="-4" y="0" z="0" />
              <参数 类型="旋转" x="0" y="0" z="0" />
              <参数 类型="缩放" x="1" y="1" z="1" />
              <几何体 形状="立方体" 宽度="2" 高度="2" 深度="2" />
              <材质 类型="高端材质" 颜色="#ff0000" 双面="是">
                  <取值 名称="高光度" 值="30" />
                  <取值 名称="镜面反射" 值="#ffffff" />
              </材质>
          </物体>
          <物体 名称="圈圈">
              <参数 类型="位置" x="0" y="0" z="0" />
              <参数 类型="旋转" x="0" y="0" z="0" />
              <参数 类型="缩放" x="1" y="1" z="1" />
              <几何体 形状="圆形" 半径="1.5" 分段数="32" />
              <材质 类型="标准" 颜色="#ffff00" 双面="是" />
          </物体>
          <物体>
              <参数 类型="位置" x="4" y="0" z="0" />
              <参数 类型="旋转" x="0" y="0" z="0" />
              <参数 类型="缩放" x="1" y="1" z="1" />
              <几何体 形状="球体" 半径="1" 横向分段数="32" 纵向分段数="16" />
              <材质 类型="高端材质" 颜色="#0000ff">
                  <取值 名称="高光度" 值="30" />
                  <取值 名称="镜面反射" 值="#ffffff" />
              </材质>
          </物体>
          <灯光 类型="环境光" 颜色="#ffffff" 强度="0.3">
          </灯光>
          <灯光 类型="点光源" 颜色="#ffffff" 强度="0.5" 距离="10">
              <参数 类型="位置" x="1" y="1" z="1" />
          </灯光>
          <模型 名称="冰墩墩" 路径="/three-js-es@1.0.0/冰墩墩.glb">
              <参数 类型="位置" x="0" y="3" z="0" />
              <参数 类型="缩放" x="5" y="5" z="5" />
          </模型>
          <自定义对象 颜色="#ff0000">
            <参数 类型="位置" x="0" y="0" z="0" />
          </自定义对象>
      </场景>
    </script>
    <script type="module">
        import * as THREE from "three";
        import 加载场景 from "/three-js-es@1.0.0";

        const 管理 = new 加载场景("#我的场景");

        let 时间 = 0; // 时间变量，用于周期性计算平移量

        管理.更新 = () => {

            const 冰墩墩 = 管理.获取对象("冰墩墩");
            冰墩墩.旋转.y += 0.01;

            const x周期 = 2; // X 位移的周期，单位为秒
            const x振幅 = 1; // X 位移的振幅
            const x速度 = 0.1; // X 位移的速度
            const x移动 = Math.sin(时间 * x速度 / x周期) * x振幅;
            冰墩墩.位置.x = x移动;

            const 圈圈 = 管理.获取对象("圈圈");
            圈圈.旋转.y += 0.01;

            时间++;

        };

        class CustomObject extends THREE.Object3D {
            constructor(elem) {
                super();
                const color = parseInt(elem.getAttribute("颜色") ? elem.getAttribute("颜色").replace("#", "") : "#ffffff", 16);
                const geometry = new THREE.SphereGeometry(0.5, 32, 32);
                const material = new THREE.MeshStandardMaterial({
                    color: color,
                    roughness: 0.4,
                    metalness: 0.5
                });
                this.mesh = new THREE.Mesh(geometry, material);
                this.add(this.mesh);
                const transform = { position: new THREE.Vector3() };
                for (const param of [...elem.getElementsByTagName("参数")]) {
                    const type = param.getAttribute("类型");
                    switch (type) {
                        case "位置":
                            transform.position.set(parseFloat(param.getAttribute("x")), parseFloat(param.getAttribute("y")), parseFloat(param.getAttribute("z")));
                            break;
                    }
                }

                const { position } = transform;
                this.position.copy(position);
                return this;
            }
        }

        管理.注册("自定义对象", "customobject", CustomObject);

        管理.运行();
    </script>
</body>

</html>